/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package InternetHax;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;
import java.util.Vector;

/**
 *
 * @author LoginError
 */
public class AppMenu extends Menu{
    Sprite[] appImages;
    Vector inventory;
    Image recharging;
    

    boolean done = false;
    int selectedIndex = 0;
    int maxIndex = 0;
    boolean pickMany = false;
    boolean cancel = false;
    boolean[] selectionMask;
    int numSelected = 0;
    int scrollOffset = 0;
    int screenLimit = 4; //todo: generate this based on height
    String title;

    public AppMenu(Sprite[] appImages)
    {
      this.appImages = appImages;
      recharging = Gamestate.resourceManager.getResourceByName("Recharging.gif");
    }

    synchronized public void indexPlus() {
        if (++selectedIndex > maxIndex) {
            selectedIndex = 0;
            scrollOffset = 0;
        }
        if (selectedIndex >= scrollOffset + screenLimit) {
            scrollOffset++;
        }
    }

    synchronized public void indexMinus() {
        if (--selectedIndex < 0) {
            selectedIndex = maxIndex;
            if(maxIndex >= screenLimit)
                scrollOffset = maxIndex - screenLimit + 1;
        }
        if (scrollOffset > 0 && selectedIndex + 1 == scrollOffset) {
            scrollOffset--;
        }
    }

    synchronized public void selectItem() {
        if (!pickMany) {
            closeMenu(false);
        } else {
            boolean isSelected = selectionMask[selectedIndex];

            if (isSelected) {
                numSelected--;
            } else {
                numSelected++;
            }
            selectionMask[selectedIndex] = !isSelected;//toggle the value for the currently selected index
        }
    }

    synchronized public void confirm() {
        closeMenu(false);
    }

    synchronized public void cancel() {
        closeMenu(true);
    }

    synchronized public void closeMenu(boolean cancel) {
        this.cancel = cancel;

        if (Gamestate.modalMenu == this) {
            Gamestate.modalMenu = null;
        }
        this.notify();
    }

    synchronized private void reset() {
        done = false;
        selectedIndex = 0;
        maxIndex = 0;
        pickMany = false;
        cancel = false;
        selectionMask = null;
        numSelected = 0;
        inventory = null;
        title = null;
    }

    /**
     *
     * @param choices an array of strings represending possible choices for the user
     * @return the index of the menu item chosen, or -1 if the user cancelled or there was an error
     * Note that pickOne will not return until closeMenu is called by another thread.
     */
    synchronized public int pickOne(String title, Vector apps) {
        reset();
        this.inventory = apps;
        this.title = title;
        this.maxIndex = apps.size()- 1;
        pickMany = false;
        Gamestate.modalMenu = this;
        try {
            this.wait();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            return -1;
        }
        return (cancel ? -1 : selectedIndex); //return -1 if the user cancelled, the index otherwise
    }

    /**
     * Overloaded version of picke me with no limit on the number of items that can be selected
     * @param title The title to display
     * @param choices an array of strings representing the menu items
     * @return
     */
    synchronized public int[] pickMany(String title, Vector apps) {
        return pickMany(title, apps);
    }

    /**
     * allows the user to chose multiple items from a menu, the items are returned conforming to the ordering of the original choices list
     * @param title The title to display
     * @param choices an array of strings representing the menu items
     * @param limit the maximum number of menu items that can be selected.
     * @return an arry of integers corresponding to the idices of the choices passed in
     * returns null on error or if the user cancelled.
     */
    synchronized public int[] pickMany(String title, Vector apps, int limit) {
        reset();
        this.inventory = apps;
        this.title = title;
        this.maxIndex = inventory.size()- 1;
        pickMany = true;
        selectionMask = new boolean[inventory.size()];
        for (int i = 0; i < selectionMask.length; i++) {
            selectionMask[i] = false;

        }
        try {
            this.wait();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            return null;
        }
        if (cancel || numSelected == 0) {
            return null;
        }
        int[] returnValues = new int[numSelected];

        int i = 0;
        //TODO: Comment this better, as it may seem a bit confusing
        for (int j = 0; j < returnValues.length; j++) {

            while (selectionMask[j] == false) {
                i++;
            }
            returnValues[j] = i;
        }
        return returnValues;
    }


    public void handleInput(int keyAction) {

        if ((keyAction == HaxCanvas.DOWN) || (keyAction == HaxCanvas.LEFT)) {
            indexPlus();
        } else if (keyAction == HaxCanvas.RIGHT || (keyAction == HaxCanvas.UP)) {
            indexMinus();
        } else if (keyAction == HaxCanvas.FIRE) {
            selectItem();
        } else if (keyAction == HaxCanvas.KEY_NUM0)
            cancel();

    }

    synchronized public void paint(Graphics g, int x, int y) {
        int width, height;
        width = 150;
        height = 100;

        g.setColor(Gamestate.uiDetailColor);
        g.fillRect(x - width / 2, y - height / 2, width, height);
        g.setColor(Gamestate.uiBackgroundColor);
        g.fillRect(x - width / 2 + 1, y - height / 2 + 1, width - 2, height - 2);

        int offset = 18;

        Gamestate.font.PrintString(g, x - width / 2 + 3, y - height / 2 + 3, title, 0, 0, Gamestate.fontColor); // print the title

        for (int i = 0 + scrollOffset; i < scrollOffset + screenLimit; i++) {
            if (i < 0 || i >= inventory.size()) {
                return;
            }

            if (i == selectedIndex) {
                g.setColor(Gamestate.uiDetailColor);
                g.drawRect(x - width / 2 + 2, y - height / 2 + 2 + offset, width - 10, 19);
            }
            App foundApp = (App) inventory.elementAt(i);

            if(foundApp == null)
                continue;

            int type = foundApp.getType();
            int imageIndex = (type/100) -1;

            appImages[imageIndex].setPosition(x - width / 2 + 3, y - height / 2 + 3 + offset );
            appImages[imageIndex].setFrame(foundApp.getAppID() - type); //todo : explain this
            appImages[imageIndex].paint(g);
            
            Gamestate.font.PrintString(g, x - width / 2 + 20, y - height / 2 + 3 + offset, ""+foundApp.appID, 0, 0, Gamestate.fontColor);

            if(type == Constants.APPTYPE_ACTIVE)
            {
                g.setColor(Gamestate.uiDetailColor);
                    g.drawRect(x - width / 2 + 22, y - height / 2  + offset + 11  , 17 , 8);

                    ActiveApp app = (ActiveApp)foundApp;
                    int percent = (100*app.charges)/(app.chargesMax);

                    if(app.isRecharging){
                        g.setClip(x -7, y - height / 2  + offset + 12, 16 *percent /100 , 7);
                        for(int w = 0; w < 4; w++)
                        {
                            g.drawImage(recharging,x - width / 2 + 20 + (w*4), y - height / 2  + offset + 12 , 0);
                        }
                        g.setClip(0, 0, Gamestate.screenWidth, Gamestate.screenHeight);
                    }
                    {
                        g.setColor(0x00FF00); //GREEN!
                        g.fillRect(x - width / 2 + 23, y - height / 2  + offset + 12  , 16 *percent /100 , 7);
                    }
                    
            }
            else if(type == Constants.APPTYPE_CONSUMABLE){
                Gamestate.font.PrintString(g, x - width / 2 + 20, y - height / 2  + offset + 12, "x"+((ConsumableApp)foundApp).uses, 0, 0, Gamestate.fontColor);
            }

            offset += 19;
        }
    }


}
